package com.bbjob.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.bbjob.client.result.ResultForDeliveryExamineeScores;
import com.bbjob.client.result.ResultForExportExamineeScores;
import com.bbjob.dto.Result;
import com.bbjob.mapper.DeliveryCommitLogMapper;
import com.bbjob.mapper.DeliveryExamineeScoresMapper;
import com.bbjob.model.DeliveryCommitLog;
import com.bbjob.model.DeliveryExamineeScores;
import com.bbjob.model.ExamineeScores;
import com.bbjob.query.QueryScores;
import com.bbjob.service.IExamineeScoresService;
import com.bbjob.service.ISystemService;
import com.bbjob.toolutil.ExeclBean;
import com.bbjob.toolutil.ExeclTool;
import com.bbjob.toolutil.HttpClientUtil;
import com.bbjob.util.Tool;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

@Service
public class ExamineeScoresService implements IExamineeScoresService{

	@Value("${sys.local.exam.answer.path}")
	private String sysLocalAnswerPath;
	@Value("${sys.uniquecode}")
	private String uniquecode;
	@Value("${examol.center.url}")
	private String centerUrl;
	@Value("${examol.center.score.list}")
	private String centerScoreListUrl;
	@Value("${examol.center.score.listAll}")
	private String centerScoreListAllUrl;
	@Value("${examol.center.score.save}")
	private String centerScoreSaveUrl;
	@Value("${examol.center.score.edit}")
	private String centerScoreEditUrl;
	@Value("${oss.accessKeyId}")
	private String accessKeyId;
	@Value("${oss.accessKeySecret}")
	private String accessKeySecret;
	@Value("${oss.endpoint}")
	private String endpoint;
	@Value("${oss.bucket}")
	private String bucket;
	@Resource
	private ISystemService systemService;
	@Resource
	private DeliveryExamineeScoresMapper deliveryExamineeScoresMapper;
	@Resource
	private DeliveryCommitLogMapper deliveryCommitLogMapper;
	
	
	@Override
	public Result selectByParams(QueryScores scores) {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("uniquecode", uniquecode);
		params.put("pageNum", scores.getPageNum());
		params.put("pageSize", scores.getPageSize());
		try {
			
			if (scores.getExamInfoId() != null) {
				params.put("examInfoId", scores.getExamInfoId());
			}
			
			if (scores.getqId() != null) {
				params.put("qId", scores.getqId());
			}
			
			if (scores.getsNo() != null) {
				params.put("sNo", scores.getsNo());
			}
			
			if (scores.getOrganSchool() != null) {
				params.put("organSchool", scores.getOrganSchool());
			}
			
			if (scores.getOrganDepart() != null) {
				params.put("organDepart", scores.getOrganDepart());
			}
			
			if (scores.getOrganGrade() != null) {
				params.put("organGrade", scores.getOrganGrade());
			}
			
			if (scores.getOrganClass() != null) {
				params.put("organClass", scores.getOrganClass());
			}
			
			String resultStr = HttpClientUtil.doPost(centerUrl + centerScoreListUrl, params);
			Result list = new Gson().fromJson(resultStr, Result.class);
			
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public DeliveryExamineeScores saveByEntity(HttpServletRequest request, MultipartFile multipartFile) {
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("uniquecode", uniquecode);
		DeliveryExamineeScores score = new DeliveryExamineeScores();
		DeliveryCommitLog log = new DeliveryCommitLog();
		log.setId(Tool.getUUID());
		
		try {
			
			if (request.getParameter("examInfoId") != null) {
				score.setExamInfoId(Integer.valueOf(request.getParameter("examInfoId")));
				params.put("examInfoId", request.getParameter("examInfoId"));
				log.seteId(Integer.valueOf(request.getParameter("examInfoId")));
			}
			
			if (request.getParameter("qId") != null && !"".equals(request.getParameter("qId"))) {
				score.setqId(request.getParameter("qId"));
				params.put("qId", request.getParameter("qId"));
			}
			
			if (request.getParameter("sNo") != null && !"".equals(request.getParameter("sNo"))) {
				score.setsNo(request.getParameter("sNo"));
				params.put("sNo", request.getParameter("sNo"));
				log.setsNo(request.getParameter("sNo"));
			}
			
			if (request.getParameter("sScore") != null) {
				score.setsScore(new BigDecimal(request.getParameter("sScore")));
				params.put("sScore", request.getParameter("sScore"));
			}
			
			if (request.getParameter("eNo") != null && !"".equals(request.getParameter("eNo"))) {
				log.seteNo(request.getParameter("eNo"));
			}
			
			if (request.getParameter("sName") != null && !"".equals(request.getParameter("sName"))) {
				log.setsName(request.getParameter("sName"));
			}
			
			
			Result testConn = systemService.TestConn();

			// 1.本地上传
			String saveDirectory = sysLocalAnswerPath + score.getExamInfoId() + "/" + score.getqId() + "/" + score.getsNo() + "/" + multipartFile.getOriginalFilename();
			File path = new File(saveDirectory);
			if (!path.getParentFile().exists()) {
				path.getParentFile().mkdirs();
				path.createNewFile();
			}
			multipartFile.transferTo(path);
			score.setqAnswerPath(saveDirectory);
			
			if (testConn.getCode() == 200) {
				// 上传答案文件
				// 2.文件上传完毕，准备传入OSS
				OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
				ossClient.putObject(bucket, multipartFile.getOriginalFilename(), new File(saveDirectory));
				params.put("qAnswerPath", multipartFile.getOriginalFilename());
				
				
				String resultStr = HttpClientUtil.doPost(centerUrl + centerScoreSaveUrl, params);
			    GsonBuilder builder = new GsonBuilder();
			    
			    builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
			    	@Override   
			    	public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
			    		return new Date(json.getAsJsonPrimitive().getAsLong()); 
			    	}
			    });
				
			    ResultForDeliveryExamineeScores result = builder.create().fromJson(resultStr, ResultForDeliveryExamineeScores.class);
				
				if (result.getCode() == 200) {
					score.setField4(1);
					score.setId(result.getData().getId());
				} else {
					
					return null;
				}
			} else {
				score.setId(Tool.getUUID());
				score.setField4(0);
			}
			
			List<DeliveryExamineeScores> items = deliveryExamineeScoresMapper.selectByParams(score);
			if (items.size() > 0) {
				score.setId(items.get(0).getId());
				score.setCreateTime(items.get(0).getCreateTime());
				deliveryExamineeScoresMapper.updateByPrimaryKey(score);
			} else {
				score.setCreateTime(new Date());
				deliveryExamineeScoresMapper.insert(score);
			}
			log.setCreateTime(new Date());
			
			List<DeliveryCommitLog> logs = deliveryCommitLogMapper.selectByParams(log);
			
			if (logs.size() > 0) {
			} else {
				deliveryCommitLogMapper.insert(log);
			}
			
			return score;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public void updateStudent(ExamineeScores scores, Integer id) {
		Map<String, Object> params = new HashMap<String, Object>();
	
		try {
			if (scores.getExamInfoId() != null) {
				params.put("examInfoId", scores.getExamInfoId());
			}
			
			if (scores.getqId() != null && !"".equals(scores.getqId())) {
				params.put("qId", scores.getqId());
			}
			
			if (scores.getsNo() != null && !"".equals(scores.getsNo())) {
				params.put("sNo", scores.getsNo());
			}
			
			if (scores.getOrganDepart() != null) {
				params.put("organDepart", scores.getOrganDepart());
			}
			
			if (scores.getOrganGrade() != null) {
				params.put("organGrade", scores.getOrganGrade());
			}
			
			if (scores.getOrganClass() != null) {
				params.put("organClass", scores.getOrganClass());
			}
			
			if (scores.getsScore() != null) {
				params.put("sScore", scores.getsScore());
			}
			
			if (scores.getqAnswerPath() != null && !"".equals(scores.getqAnswerPath())) {
				params.put("qAnswerPath", scores.getqAnswerPath());
			}
			
			String resultStr = HttpClientUtil.doPost(centerUrl + centerScoreEditUrl  + id, params);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	
	}

	@Override
	public void exportByParams(QueryScores scores, HttpServletResponse response) {

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("uniquecode", uniquecode);
		try {
			
			if (scores.getExamInfoId() != null) {
				params.put("examInfoId", scores.getExamInfoId());
			}
			
			if (scores.getqId() != null) {
				params.put("qId", scores.getqId());
			}
			
			if (scores.getsNo() != null) {
				params.put("sNo", scores.getsNo());
			}
			
			if (scores.getOrganSchool() != null) {
				params.put("organSchool", scores.getOrganSchool());
			}
			
			if (scores.getOrganDepart() != null) {
				params.put("organDepart", scores.getOrganDepart());
			}
			
			if (scores.getOrganGrade() != null) {
				params.put("organGrade", scores.getOrganGrade());
			}
			
			if (scores.getOrganClass() != null) {
				params.put("organClass", scores.getOrganClass());
			}
			
			String resultStr = HttpClientUtil.doPost(centerUrl + centerScoreListAllUrl, params);
		    GsonBuilder builder = new GsonBuilder();
		    
		    builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
		    	@Override   
		    	public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
		    		return new Date(json.getAsJsonPrimitive().getAsLong()); 
		    	}
		    });
			
		    ResultForExportExamineeScores result = builder.create().fromJson(resultStr, ResultForExportExamineeScores.class);
			

			// 处理返回值准备导出Excel
		    if (result.getCode() == 200) {
			    List<ExamineeScores> datas = result.getData();
			    
			    try {
			    	String title = "";
			    	
			    	if (datas.size() > 0) {
			    		title = datas.get(0).geteName() + "-" + datas.get(0).getqTitle() + "--" + "成绩表";
			    	}
			    	List<ExeclBean> headers = getExcel();
			    	response.reset();
			    	setDownloadResponseHeader(response, "成绩信息表.xls");
			    	ExeclTool.getInstance().exportExecl(title, headers, datas, response.getOutputStream());
			    	
			    } catch (Exception e) {
			    	e.printStackTrace();
			    }
		    }

		    
			System.out.println(resultStr);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private List<ExeclBean> getExcel() {
		List<ExeclBean> list = new ArrayList<ExeclBean>();
		
		list.add(new ExeclBean("学校", "getSchoolName"));
		list.add(new ExeclBean("系", "getDepartName"));
		list.add(new ExeclBean("年级", "getGradeName"));
		list.add(new ExeclBean("班级", "getClassName"));
		list.add(new ExeclBean("学号", "getsNo"));
		list.add(new ExeclBean("姓名", "getsName"));
		list.add(new ExeclBean("成绩", "getsScore"));
		
		return list;
	}
	
	public void setDownloadResponseHeader(HttpServletResponse response,
			String filename) {
		response.setCharacterEncoding("utf-8");
		response.setContentType("application/vnd.ms-excel;charset=utf-8");
		try {
			filename = new String(filename.getBytes("utf-8"),"iso-8859-1");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		response.setHeader("Content-disposition", "attachment; filename="
				+ filename);
	}
	
	@Override
	public String downloadAnswerFile(String filePath, HttpServletResponse response) {
		try {
			Result testConn = systemService.TestConn();
			if (testConn.getCode() == 200) {
				response.setContentType("application/octet-stream");// 
                response.setHeader("content-type", "application/octet-stream");
                response.setHeader("Content-Disposition", "attachment;fileName=" + filePath);
				
				byte[] bytes = getBytesFromOss(filePath);
				HttpHeaders headers=new HttpHeaders();
			
			    headers.add("Last-Modified", new Date().toString());
				headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
				
				OutputStream os = response.getOutputStream();
				os.write(bytes);
			} else {
			}
		} catch(Exception e) {
			e.printStackTrace();
		}		
		return null;
	}

	private byte[] getBytesFromOss(String key) throws IOException {
		byte[] bytes=null;
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		InputStream is= ossClient.getObject(bucket, key).getResponse().getContent();
		ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int r = 0;
			try {
				while ((r = is.read(buffer)) > 0) {
				      output.write(buffer, 0, r); 			      
				  }
				bytes=output.toByteArray();
				output.flush();
			      output.close();
			} catch (IOException e) {
				e.printStackTrace();
				throw e;
			}
			return bytes;
	}

	public Result syncScores(ExamineeScores scoreEntity) {
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("uniquecode", uniquecode);
		
		try {
			
			if (scoreEntity.getExamInfoId() != null) {
				params.put("examInfoId", scoreEntity.getExamInfoId());
			}
			
			if (scoreEntity.getqId() != null && !"".equals(scoreEntity.getqId())) {
				params.put("qId", scoreEntity.getqId());
			}
			
			if (scoreEntity.getsNo() != null && !"".equals(scoreEntity.getsNo())) {
				params.put("sNo", scoreEntity.getsNo());
			}
			
			if (scoreEntity.getsScore() != null) {
				params.put("sScore", scoreEntity.getsScore());
			}
			
			if (scoreEntity.getqAnswerPath() != null) {
				params.put("qAnswerPath", scoreEntity.getqAnswerPath());
			}
				
			String resultStr = HttpClientUtil.doPost(centerUrl + centerScoreSaveUrl, params);
			GsonBuilder builder = new GsonBuilder();
			    
			builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
				@Override   
				public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
					return new Date(json.getAsJsonPrimitive().getAsLong()); 
				}
			});
				
			ResultForDeliveryExamineeScores result = builder.create().fromJson(resultStr, ResultForDeliveryExamineeScores.class);
				
			if (result.getCode() == 200) {

				return new Result();
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
